package sj;

import lombok.extern.slf4j.Slf4j;

/**
 * 死锁
 * 。。柜员张三：账户A 转给账户B 100元，
 * 此时柜员李四：账户B 转给账户A 100元。
 * 可能凑巧张三拿到了账本A，李四拿到了账本B。
 * 。张三拿到账本A 后就等着账本B（账本B 已经被李四拿走），
 * 而李四拿到账本B 后就等着账本A（账本A 已经被张三拿走），
 * 他们要等多久呢？他们会永远等待下去……因为张三不会把账本A 送回去，李四也不会把账本B 送回去。
 */
@Slf4j
public class Account1_synchronized_dead {

    public static void main(String[] args) throws InterruptedException {
        Account a = new Account(200);//A账户的初始金额200
        Account b = new Account(300);//B账户的初始金额300

        Thread thread1 = new Thread(() -> {
            try {
                transfer(a, b, 100);
            } catch (InterruptedException e) {
            }
        });
        Thread thread2 = new Thread(() -> {
            try {
                transfer(b, a, 100);
            } catch (InterruptedException e) {
            }
        });

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println("成功");
    }

    /*锁定转出账户。Thread1锁定了A，Thread2锁定了B
      锁定转入账户。Thread1需要获取到B，可是B被Thread2锁定了。
      、、、、、、、Thread2需要获取的A，可是A被Thread2锁定了。
      所以互相等待。死锁。
    */
    static void transfer(Account soure, Account target, int amt) throws InterruptedException {
        synchronized (soure) { //-----锁定转出账户
            Thread.sleep(1000);
            log.info("持有锁{} 等待锁{}", soure, target);
            synchronized (target) { //锁定转入账户
                if (soure.getBalance() > amt) {
                    soure.setBalance(soure.getBalance() - amt);
                    target.setBalance(target.getBalance() + amt);
                }
            }
        }
    }
}
